using System.Text;
using System.Web.Mvc;
using Res = System.Resources;

namespace WineCellar.Web.Helpers
{
    public static class HtmlHelperExtensions
    {
        /// <summary>
        /// Renders an ExtJs grid.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <param name="targetDivId">The target div id.</param>
        /// <param name="defaultSortColumn">The default sort column.</param>
        /// <param name="url">The URL.</param>
        /// <param name="records">The records.</param>
        /// <param name="filters">The filters.</param>
        /// <param name="columns">The columns.</param>
        /// <param name="title">The title.</param>
        /// <param name="resourceManager">The resource manager.</param>
        /// <returns></returns>
        public static string ExtJsGrid(this HtmlHelper htmlHelper,string targetDivId, string defaultSortColumn, string url,
                                        ExtRecord[] records, ExtFilter[] filters, ExtColumnModel[] columns,
                                        string title,Res.ResourceManager resourceManager)
        {
            return CreateGrid(targetDivId, defaultSortColumn, url, records, filters, columns, title, resourceManager, "grid");
        }

        /// <summary>
        /// Renders an ExtJs grid.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <param name="targetDivId">The target div id.</param>
        /// <param name="defaultSortColumn">The default sort column.</param>
        /// <param name="url">The URL.</param>
        /// <param name="records">The records.</param>
        /// <param name="filters">The filters.</param>
        /// <param name="columns">The columns.</param>
        /// <param name="title">The title.</param>
        /// <param name="resourceManager">The resource manager.</param>
        /// <param name="gridIdentifier">The grid identifier, use this value as a variable name (for instance in Javascript operations).</param>
        /// <returns></returns>
        public static string ExtJsGrid(this HtmlHelper htmlHelper,string targetDivId, string defaultSortColumn, string url,
                                        ExtRecord[] records, ExtFilter[] filters, ExtColumnModel[] columns,
                                        string title,Res.ResourceManager resourceManager,  string gridIdentifier)
        {
            return CreateGrid(targetDivId, defaultSortColumn, url, records, filters, columns, title, resourceManager, gridIdentifier);
        }

        public static string ExtJsGrid(this HtmlHelper htmlHelper, string targetDivId, string defaultSortColumn, string url,
                                        ExtRecord[] records, ExtFilter[] filters, ExtColumnModel[] columns,
                                        string title, Res.ResourceManager resourceManager, string gridIdentifier, 
                                        bool script)
        {
            return CreateGrid(targetDivId, defaultSortColumn, url, records, filters, columns, title, resourceManager, gridIdentifier, script);
        }

        private static string CreateGrid(string targetDivId, string defaultSortColumn, string url,
                                        ExtRecord[] records, ExtFilter[] filters, ExtColumnModel[] columns,
                                        string title, Res.ResourceManager resourceManager, string gridIdentifier)
        {
            return CreateGrid(targetDivId, defaultSortColumn, url, records, filters, columns, title, resourceManager, gridIdentifier, true);
        }

        private static string CreateGrid(string targetDivId, string defaultSortColumn, string url,
                                        ExtRecord[] records, ExtFilter[] filters, ExtColumnModel[] columns,
                                        string title, Res.ResourceManager resourceManager, string gridIdentifier, 
                                        bool standalone)
        {
            var sb = new StringBuilder();
            if (standalone)
            {
                sb.AppendLine(@"<div id='filters'></div><br/>");
                sb.AppendLine(@"<script language=""javascript"" type=""text/javascript"">");
                sb.AppendLine("Ext.onReady(function(){");
            }
            sb.AppendLine("Ext.QuickTips.init();");
            sb.AppendLine("Ext.state.Manager.setProvider(new Ext.state.CookieProvider());");
            sb.AppendLine("entity = Ext.data.Record.create([");
            //Create Ext.Data.Record
            for (var i = 0; i < records.Length; i++)
            {
                if (i == records.Length - 1)
                {
                    sb.AppendLine(records[i].JavaScriptString + "]);");
                }
                else
                {
                    sb.Append(records[i].JavaScriptString + ",");
                }
            }
            sb.AppendLine("entityReader = new Ext.data.JsonReader({ ");
            sb.AppendLine(@"root: ""root"",");
            sb.AppendLine(@"totalProperty: ""totalcount"",");
            sb.AppendLine(@"id: ""id""},entity);");
            sb.AppendLine("ds = new Ext.data.Store({");
            sb.AppendLine(@"url: baseUrl +'" + url + "',");
            sb.AppendLine(@"reader: entityReader, sortinfo:{field: " + JsonEncoder.Enquote(defaultSortColumn) + @",direction:""ASC""},remoteSort:true});");
            //filters
            sb.AppendLine(@"var filters = new Ext.ux.grid.GridFilters({filters:[");
            for (var j = 0; j < filters.Length; j++)
            {
                if (j == filters.Length - 1)
                {
                    sb.AppendLine(filters[j].JavaScriptString + "]});");
                }
                else
                {
                    sb.Append(filters[j].JavaScriptString + ",");
                }
            }
            sb.AppendLine(@"var sm = new Ext.grid.CheckboxSelectionModel({singleSelect:true});");
            sb.AppendLine(@"columnModel = new Ext.grid.ColumnModel([sm,");
            for (var j = 0; j < columns.Length; j++)
            {
                if (j == columns.Length - 1)
                {
                    sb.AppendLine(columns[j].JavaScriptString + "]);");
                }
                else
                {
                    sb.Append(columns[j].JavaScriptString + ",");
                }
            }
            sb.AppendLine(@"columnModel.defaultSortable = true;");
            sb.AppendLine(@"var paging = new Ext.PagingToolbar({store: ds,pageSize: 10,plugins: filters,displayInfo:true})");
            sb.AppendLine(gridIdentifier + " = new Ext.grid.EditorGridPanel({");
            sb.AppendLine("store:ds, cm:columnModel, width:780, height: 300,");
            sb.AppendLine(@"title: '" + title + "',");
            sb.AppendLine("frame:true, loadmask: true, trackmouseover: true, selModel: sm,");
            sb.AppendLine(@"view: new Ext.grid.GridView({forceFit:false,autoFill:true}),");
            sb.AppendLine(@"plugins:[new Ext.ux.grid.Search({minChars:3,autoFocus:true,width:250}),filters],");
            sb.AppendLine(@"bbar: paging");
            //close grid declaration
            sb.AppendLine(@"});");
            //render grid
            sb.AppendLine(gridIdentifier + @".render('" + targetDivId + "');");
            //add button to paging toolbar
            sb.AppendLine(@"function clearFilterFunction() {filters.clearFilters();}");
            sb.AppendLine(@"paging.addButton([{text:'" + resourceManager.GetString("ClearAllFilters") + "', handler:clearFilterFunction}]);");
            sb.AppendLine(@"ds.load({params:{start:0, limit:10}});");
            //filter feedback when updating the filters
            sb.AppendLine(gridIdentifier + @".on('filterupdate',function(GridFilter,filter){");
            sb.AppendLine(ShowFilterFeedback(gridIdentifier, resourceManager));
            sb.AppendLine(@"Ext.apply(cm.config[idx],{filterActive : filter.active,filterClass:GridFilter.filterCls});}," + gridIdentifier + ");");
            //filter feedback when rendering the grid            
            sb.AppendLine(ShowFilterFeedback(gridIdentifier, resourceManager));                        
            //close ExtJs ready
            if (standalone)
            {
                sb.AppendLine("});");
                sb.AppendLine("</script>");
            }

            return sb.ToString();
        }
        private static string ShowFilterFeedback(string gridIdentifier, Res.ResourceManager resourceManager)
        {
            var sb = new StringBuilder();            
            sb.AppendLine(@"var cm=" + gridIdentifier + @".getColumnModel();");
            sb.AppendLine(@"var msg = '<p><h2>" + resourceManager.GetString("Filterfeedback") + @"</h2></p><ul>';");
            sb.AppendLine(@"var curFilters = " + gridIdentifier + @".filters.getFilterData();");
            sb.AppendLine(@"for(var i = 0; i < curFilters.length;i++)");
            sb.AppendLine(@"{msg = msg + '<li>';");
            sb.AppendLine(@"var idx=cm.findColumnIndex(curFilters[i].field);");
            sb.AppendLine(@"var header = cm.getColumnHeader(idx);");
            sb.AppendLine(@"msg = msg + header +  ':<b>' + curFilters[i].data.value +  '</b></li>';}");
            sb.AppendLine(@"msg = msg + '</ul>';");
            sb.AppendLine(@"$('#filters').html(msg);");            
            return sb.ToString();
        }
    }
}